#include "GAF_Player.h"
#include "GAF_Platform.h"

#define GAF_PLAYER_CHECK(_Do, _f) \
	if((int)(_f) == 0) \
	{ \
		GAF_LOG("Check \"%s\" Player Do %s,\t<%s> is FALSE!", GetPlayerName_a().c_str(), ""#_Do, ""#_f); \
		return; \
	}


namespace GAF
{
	UINT Player::m_nID = 0;
	UINT Player::GetID()
	{
		return m_nID++;
	}

	Player::Player()
	{
		static char _szPlayerName[20];
		SYS_MEMSET(_szPlayerName, 0, sizeof(_szPlayerName));
		SYS_SPRINTF(_szPlayerName, "P_%d", GetID());

		ATTRIB(PlayerName)	= _szPlayerName;
		ATTRIB(State)		= PLAYER_STOP;
		ATTRIB(Loop)		= false;
		ATTRIB(Interval)	= 0;

		m_pResponse		= NULL;
		m_pTimer		= NULL;
		m_isExactTimer		= false;
	}

	Player::~Player()
	{
		if(m_pTimer != NULL)
			GAF_DELETE(m_pTimer);
	}

	void Player::ExactTimer()
	{
		m_isExactTimer = true;
	}

	void Player::SetResponse(PlayerResponse* pResponse)
	{
		GAF_CHECK(pResponse != NULL);

		m_pResponse = pResponse;
	}

	void Player::Play(Bundle* pbdlParam)
	{
		GAF_PLAYER_CHECK(Play, ATTRIB(State) != PLAYER_PLAY);

		if(OnPlay(pbdlParam))
		{
			if(Playing(pbdlParam))
			{
				if(m_pTimer == NULL)
					m_pTimer = GAF_NEW(Timer);

				m_pTimer->SetRunClass_a(this);
				if(m_isExactTimer)
					m_pTimer->Exact();
				m_pTimer->SetInterval_a(ATTRIB(Interval));
				m_pTimer->Start();

				m_ttLast = GAF_pTHEPLATFORM->GetTimeTicks();

				ATTRIB(State) = PLAYER_PLAY;
				if(m_pResponse != NULL)
				{
					m_pResponse->OnPlayerResponse(this, PLAYER_PLAY);
				}
			}
		}
	}

	void Player::Pause()
	{
		GAF_PLAYER_CHECK(Pause, ATTRIB(State) == PLAYER_PLAY);

		if(OnPause())
		{
			if(Pauseing())
			{
				m_pTimer->Stop();

				ATTRIB(State) = PLAYER_PAUSE;
				if(m_pResponse != NULL)
				{
					m_pResponse->OnPlayerResponse(this, PLAYER_PAUSE);
				}
			}
		}
	}

        void Player::Finish()
        {
                // 		GAF_PLAYER_CHECK(Finish, ATTRIB(State) == PLAYER_RUN);

                if(OnFinish())
                {
                        if(Finishing())
                        {
                                ATTRIB(State) = PLAYER_FINISH;

                                if(m_pResponse != NULL)
                                {
                                        this->m_pResponse->OnPlayerResponse(this, PLAYER_FINISH);
                                }
                        }
                }
        }

        void Player::Stop()
        {
                GAF_PLAYER_CHECK(Stop, ATTRIB(State) != PLAYER_STOP);

                if(OnStop())
                {
                        if(Stopping())
                        {
                                m_pTimer->Stop();

                                ATTRIB(State) = PLAYER_STOP;
                                if(m_pResponse != NULL)
                                {
                                        m_pResponse->OnPlayerResponse(this, PLAYER_STOP);
                                }
                        }
                }
        }

	void Player::OnRun(RunBase* pRunBase)
	{
		if(pRunBase == m_pTimer)
		{
			GAF_PLAYER_CHECK(Run, ATTRIB(State) != PLAYER_PAUSE);
			GAF_PLAYER_CHECK(Run, ATTRIB(State) != PLAYER_STOP);

			TimeTicks _ttNow = GAF_pTHEPLATFORM->GetTimeTicks();
			TimeTicks _ttUsed = _ttNow - m_ttLast;

			bool _isContinue = false;
			bool _isFinish = false;

			_isContinue = OnUpdate(_ttUsed, _isFinish);

			if(_isContinue)
			{
				_isContinue = Running(_ttUsed, _isFinish);

				if(_isContinue)
				{
					ATTRIB(State) = PLAYER_RUN;
					m_ttLast = _ttNow;
					
					if(m_pResponse != NULL)
					{
						m_pResponse->OnPlayerResponse(this, PLAYER_RUN);
					}
				}
			}

                        if(!_isContinue)
                                _isFinish = true;

			if(_isFinish)
				Finish();

			if(!_isContinue)
				Stop();
		}
	}

	void Player::SetPlayerName(STD_STRING strPlayerName)
	{
		if(ATTRIB(PlayerName).substr(0, 2) == "P_")
			ATTRIB(PlayerName) = strPlayerName;
	}
}
